package com.ms.qw.server.infrastructure.persistence.jpa;

import org.springframework.util.StringUtils;

import javax.persistence.Query;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * User: gmc
 * Date: 13/12/11
 */
public class WhereBuilder {
    private StringBuilder where;
    private Map<String, Object> params;

    public WhereBuilder() {
        where = new StringBuilder();
        params = new HashMap<String, Object>();
    }

    public String appendSql(String sqlFragment, String paramName, Object value) {
        if (value != null) {
            boolean valueIsEmpty = (value instanceof String) && (!StringUtils.hasText((String) value));
            if (valueIsEmpty) {
                return "";
            }
            where.append(sqlFragment);
            params.put(paramName, value);
            return sqlFragment;
        }
        return "";
    }

    public String append(String colName, String paramName, Object value) {
        StringBuffer whereTemp = new StringBuffer();
        if (value != null) {
            boolean valueIsEmpty = (value instanceof String) && (!StringUtils.hasText((String) value));
            if (!valueIsEmpty) {
                whereTemp.append(" and ");
                whereTemp.append(colName);
                whereTemp.append("=");
                whereTemp.append(":");
                whereTemp.append(paramName);
                params.put(paramName, value);
                where.append(whereTemp);
            }
        }
        return whereTemp.toString();
    }

    public void appendBetween(String colName, String paramNamePrefix, Date feInicial, Date feFinal) {
        if (feInicial != null && feFinal != null) {
            where.append(" and ");
            where.append(colName);
            where.append(" between ");
            where.append(":");
            where.append(paramNamePrefix + "Inicial");
            where.append(" and  :");
            where.append(paramNamePrefix + "Final");
            params.put(paramNamePrefix + "Inicial", feInicial);
            params.put(paramNamePrefix + "Final", feFinal);
        }
    }


    public void populateParameters(Query query) {
        for (String key : params.keySet()) {
            query.setParameter(key, params.get(key));
        }
    }

    public void populateParameters(org.hibernate.Query query) {
        for (String key : params.keySet()) {
            query.setParameter(key, params.get(key));
        }
    }
    public org.hibernate.Query populateParameters2(org.hibernate.Query query) {
        for (String key : params.keySet()) {
            query.setParameter(key, params.get(key));
        }
        return query;
    }

    @Override
    public String toString() {
        return where.toString();
    }

    public String appendLike(String colName, String paramName, String value, boolean includeNonStarting) {
        if (StringUtils.hasText(value)) {
            StringBuffer whereTemp = new StringBuffer();
            whereTemp.append(" and ");
            whereTemp.append("upper(" + colName + ")");
            whereTemp.append(" like ");
            whereTemp.append(":");
            whereTemp.append(paramName);
            where.append(whereTemp);
            String valueExt = includeNonStarting ? "%" : "";
            valueExt += value.toUpperCase() + "%";
            params.put(paramName, valueExt);
            return whereTemp.toString();
        } else
            return "";
    }

    public String appendIn(String colName, String paramName, List itemList) {
        return appendIn(colName, paramName, itemList, true);
    }

    public String appendNotIn(String colName, String paramName, List itemList) {
        return appendIn(colName, paramName, itemList, false);
    }

    private String appendIn(String colName, String paramName, List itemList, boolean in) {
        if (itemList != null && !itemList.isEmpty()) {
            StringBuffer whereTemp = new StringBuffer();
            whereTemp.append(" and ");
            whereTemp.append(colName);
            whereTemp.append(in ? "" : " not ");
            whereTemp.append(" in ");
            whereTemp.append(" (");
            for (int i = 0; i < itemList.size(); i++) {
                Object paramVal = itemList.get(i);
                if (i > 0) whereTemp.append(",");
                whereTemp.append(":" + paramName + i);
                params.put(paramName + i, paramVal);
            }
            whereTemp.append(")");
            where.append(whereTemp);
            return whereTemp.toString();
        } else
            return "";
    }
}
